import { Component, NgZone, OnInit, ViewChild } from '@angular/core';
import { AlertController, IonContent, ModalController } from '@ionic/angular';
import { toByteArray } from 'base64-js';
import { isString } from 'lodash';
import { pb } from 'src/pb';
import { CallService } from '../call.service';
import { sleep } from '../utils';
import { SettingsPage } from './settings/settings.page';

@Component({
  selector: 'app-ping',
  templateUrl: './ping.page.html',
  styleUrls: ['./ping.page.scss'],
})
export class PingPage implements OnInit {
  @ViewChild(IonContent, { static: true })
  content: IonContent;
  address = 'gitee.com';
  res: pb.PingResponse[] = [];
  id = 0;
  isPing = false;
  private setting: pb.IPingSettings = {
    count: 5,
    timeout: 10,
    size: 24,
    interval: 1,
  };
  constructor(
    private callService: CallService,
    private alertCtrl: AlertController,
    private modalCtrl: ModalController,
    private zone: NgZone,
  ) { }

  async ngOnInit() {
    const setting = await this.callService.call('get', { def: this.setting }, 'ping');
    if (setting) {
      Object.assign(this.setting, setting);
    }
  }

  read(bs: any) {
    return new Promise<pb.PingResponse>((resolve) => {
      const reader = new FileReader();
      reader.onload = (e) => {
        const buf = new Uint8Array(e.target.result as ArrayBuffer);
        resolve(pb.PingResponse.decode(buf));
      };
      reader.readAsArrayBuffer(bs);
    });
  }

  async ping() {
    if (this.isPing) {
      return;
    }
    this.isPing = true;
    const req = new pb.PingRequest({ addr: this.address, settings: this.setting });
    this.id = await this.callService.call('ping', { def: 3 }, req);

    while (true) {
      const r = await this.callService.call('pingCall', {
        def: {
          type: pb.PingType.stats,
          stats: {
            addr: 'localhost', ipAddr: '127.0.0.1',
            packetsSent: 5, packetsRecv: 5, packetLoss: 0.0123456,
            minRtt: 19029209, avgRtt: 108585854, maxRtt: 262548236, stdDevRtt: 104762848
          }
        }
        // def: {
        //   type: pb.PingType.packet,
        //   stats: {
        //     addr: 'localhost', ipAddr: '127.0.0.1',
        //     bytes: 24, seq: 1, ttl: 51, rtt: 3333,
        //   }
        // }
      }, this.id);
      const pingRes = isString(r) ? pb.PingResponse.decode(toByteArray(r)) : new pb.PingResponse(r);
      let exit = false;
      switch (pingRes.type) {
        case pb.PingType.error:
          exit = true;
          const alert = await this.alertCtrl.create({
            header: '异常',
            subHeader: '网络测试异常',
            message: pingRes.error,
            buttons: ['关闭']
          });
          await alert.present();
          break;
        case pb.PingType.stats:
          exit = true;
          pingRes.stats.packetLoss = Math.round(pingRes.stats.packetLoss * 10000) / 100;
        // eslint-disable-next-line no-fallthrough
        case pb.PingType.packet:
          this.zone.run(() => {
            this.res.push(pingRes);
          });
          await sleep(100);
          this.content.scrollToBottom();
          break;
      }
      if (exit) {
        break;
      }
    }
    this.isPing = false;
  }

  async settings() {
    const modal = await this.modalCtrl.create({
      component: SettingsPage,
      componentProps: { setting: Object.assign({}, this.setting) },
    });
    await modal.present();
    const r = await modal.onDidDismiss();
    if (r.data) {
      await this.callService.call('set', { msg: '保存设置' }, 'ping', r.data);
      this.setting = r.data;
    }
  }
}
